package com.zxjbyte.yiyi.framework.web.config;

import com.zxjbyte.yiyi.framework.web.context.CryptoAlgorithm;
import com.zxjbyte.yiyi.framework.web.context.CryptoMode;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.ArrayList;
import java.util.List;

/**
 * API 相关配置属性类
 *
 * @Author zhangxingjia
 * @Date 2025/11/1 13:51
 * @Version: 1.0
 */
@Getter
@Setter
@ConfigurationProperties(prefix = ApiProperties.CRYPTO_PROP_PREFIX)
public class ApiProperties {

    public static final String CRYPTO_PROP_PREFIX = "yiyi.api";

    private Crypto crypto = new Crypto();

    /**
     * API 加解密配置属性类
     * <p>用于配置API接口的请求解密和响应加密相关参数</p>
     */
    @Getter
    @Setter
    public static class Crypto{
        /**
         * 开启接口
         */
        private Boolean enabled = false;

        /**
         * 调试模式
         * <p>默认值：false</p>
         * <p>开启后会在日志中输出加解密过程的详细信息</p>
         */
        private Boolean debugMode = false;

        /**
         * 加解密模式
         */
        private DefaultCryptoMode defaultMode = DefaultCryptoMode.ALL;

        /**
         * 加解密算法类型
         * 默认AES算法
         */
        private CryptoAlgorithm algorithm = CryptoAlgorithm.AES;

        /**
         * 全局默认密钥
         */
        private String defaultSecretKey = "";

        /**
         * 包含路径模式列表
         * <p>当接口没有@ApiCrypto注解时，检查是否匹配包含路径</p>
         * <p>如果为空，则没有接口进行加解密 </p>
         * <p>如果所有接口进行加解密（除了配除列表）配置 /** </p>
         */
        private List<String> includePaths = new ArrayList<>();

        /**
         * 排除路径列表
         * <p>配置在此列表中的接口路径将跳过加解密处理</p>
         */
        private List<String> excludePaths = new ArrayList<>();

        /**
         * AES 算法特定配置
         */
        private AesConfig aes = new AesConfig();

        /**
         * RSA 算法特定配置
         */
        private RsaConfig rsa = new RsaConfig();

        /**
         * SM4 算法特定配置
         */
        private Sm4Config sm4 = new Sm4Config();

        /**
         * AES 算法配置类
         */
        @Getter
        @Setter
        public static class AesConfig {
            private String mode = "CBC";
            private String padding = "PKCS5Padding";
            /**
             * 初始化向量，必须为16字节
             * 用于CBC模式，增加加密安全性
             */
            private String iv = "5a8e3d1b6f4c7a29";
            /**
             * 密钥，支持三种密钥长度：128、192、256位
             * 128-bit: 需要 16 字节密钥
             * 192-bit: 需要 24 字节密钥
             * 256-bit: 需要 32 字节密钥
             */
            private String secretKey = "FEC6CD0C7F3B44D8959B04E2799613BE";
        }

        /**
         * RSA 算法配置类
         */
        @Getter
        @Setter
        public static class RsaConfig {
            // 公钥（加密）
            private String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBm5E/YMQTy8TjcEZTX5wQXweNMHBUCMPyY7CayHusIu6xwAJdwK5LFc24ccoKDJvBKEUT2T5hhV33AhygkS8sd00bTHeAXB7aPDu0n9NnsYknrCQ9cQ9BtjDUd12Wcr9GH/qe7U/aEQDFJl670k0Nqub1rKW/erIlt2hF+aVIJQIDAQAB";
            // 私钥（解密）
            private String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMGbkT9gxBPLxONwRlNfnBBfB40wcFQIw/JjsJrIe6wi7rHAAl3ArksVzbhxygoMm8EoRRPZPmGFXfcCHKCRLyx3TRtMd4BcHto8O7Sf02exiSesJD1xD0G2MNR3XZZyv0Yf+p7tT9oRAMUmXrvSTQ2q5vWspb96siW3aEX5pUglAgMBAAECgYAq+7TVk1A07Op7bDPQ0ss9PzvX9scZgRCvwb41vwjmAKNpxy0/T0Xi2aZgqrKmZII38g7UB0k4MXnZGxjr9Q+5tqhos2069BcZMX2UZrQiTChrUfrWk3BNm0rMIS3DsC98nBgwYZB/fJU+EdkCUOXzNKNdx77HaMK0QIt/AqrBwQJBAOQ9unAUKuXIGklllojuUw3UFIbJZy/v/OMg721IqQBD42TuIPGddWVhDQ9urClrLt71Bqft2Hf7ucCMzJJi4rkCQQDZJ4eAVbWBSB+v/7Z87vx+pARuDXJQD99zulxCmN78Qu2zC/25PppZjOGp8Dv220DAo6p8YuaPrYBIE/XdLorNAkAQ6kY78jKvruHL2LyMT2VWXAZdauW71sReLN2xsrXbsCxVGZTVcz71EXk/UItv0mK54Vzp6yWk1sIQdB7hJnT5AkBQMvUsRHtAP+7UBVDUWz8NVm38ZyLsxq/0AcPJJMRVzjITij4uiBxhLlK5fGvpA5iqjMeOIMieD6ns9NI82c+RAkEA0WJ6A5+UfXAuvOq8IKSfJoA97X1CDAluNt1KCL/MXMPNzLAGn1cw6+CzeCZQuJ6E1HFOyZv3FY28W6U8C+AZcA==";
            // 密钥长度: 推荐使用1024,2048 ，不允许低于1024
            private Integer keySize = 1024;
            private String padding = "RSA/ECB/PKCS1Padding";
        }

        /**
         * SM4 算法配置类
         */
        @Getter
        @Setter
        public static class Sm4Config {
            private String mode = "CBC";
            private String padding = "PKCS5Padding";
            private String iv = "3hzph7tw2jqx6jip";
            // 密钥，支持密钥长度：128位
            private String secretKey = "PE30IKG04Z86O1T9";
        }

        /**
         * 默认加密模式
         */
        @AllArgsConstructor
        public enum DefaultCryptoMode implements CryptoMode {
            /**
             * 仅请求解密
             */
            REQUEST_ONLY(CODE_REQUEST_ONLY, "只对请求进行解密，响应不加密"),
            /**
             * 仅响应加密
             */
            RESPONSE_ONLY(CODE_RESPONSE_ONLY, "只对响应进行加密，请求不解密"),
            /**
             * 请求解密和响应加密
             */
            ALL(CODE_ALL,"请求解密和响应加密都开启");

            private final String code;
            private final String description;

            @Override
            public String getCode() {
                return code;
            }

            @Override
            public String getDescription() {
                return description;
            }
        }
    }
}
